package members

import (
	"context"
	"encoding/json"
	"errors"
	"net/http"

	"dash/jwt"

	kithttp "github.com/go-kit/kit/transport/http"
	"github.com/gorilla/mux"
)

func MakeHandler(ms MemberService, cus CollectorUserService) http.Handler {
	getCardHandler := kithttp.NewServer(
		makeCardEndpoint(ms),
		decodeGetCardRequest,
		encodeResponse)
	getDetailHandler := kithttp.NewServer(
		makeDetailEndpoint(ms, cus),
		decodeGetDetailDetailRequest,
		encodeResponse)
	updateCardHandler := kithttp.NewServer(
		makeUpdateCardEndpoint(ms),
		decodeUpdateCardRequest,
		encodeResponse)
	updateDetailHandler := kithttp.NewServer(
		makeUpdateMemberEndpoint(ms),
		decodeUpdateDetailRequest,
		encodeResponse)

	r := mux.NewRouter()
	r.Handle("/api/v1/member/card", getCardHandler).Methods("GET")
	r.Handle("/api/v1/member/card", updateCardHandler).Methods("PUT")
	r.Handle("/api/v1/member/detail", getDetailHandler).Methods("GET")
	r.Handle("/api/v1/member/detail", updateDetailHandler).Methods("PUT")
	return r
}

var ErrUserUndefined = errors.New("user not defined")

func decodeGetCardRequest(_ context.Context, r *http.Request) (interface{}, error) {
	err := r.ParseForm()
	if err != nil {
		return nil, err
	}
	id := r.Form.Get("id")
	user := r.Context().Value("user").(*jwt.User)
	if user == nil{
		return nil, ErrUserUndefined
	}
	return getCardRequest{
		Id:     id,
		UserId: user.Id,
	}, nil
}

func decodeGetDetailDetailRequest(_ context.Context, r *http.Request) (interface{}, error) {
	err := r.ParseForm()
	if err != nil {
		return nil, err
	}
	id := r.Form.Get("id")
	user := r.Context().Value("user").(*jwt.User)
	if user == nil {
		return nil, ErrUserUndefined
	}
	return getDetailRequest{
		Id:     id,
		UserId: user.Id,
	}, nil
}

func decodeUpdateCardRequest(_ context.Context, r *http.Request) (interface{}, error) {
	var request updateCardRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, err
	}
	return request, nil
}

func decodeUpdateDetailRequest(_ context.Context, r *http.Request) (interface{}, error) {
	var request updateDetailRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, err
	}
	return request, nil
}

func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}
